package com.rocksea.app.rslib;
/**
 * Created by IntelliJ IDEA.
 * User: 张伟
 * Date: 2011-12-26
 */
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;

class JyLineStyle
{
	float dash[] = new float[0]; // 线型
	float lineWidth = 4.5f; // 线宽
	int lineColor = Color.rgb(1,255,5); // 线的颜色
}

class JyFontStyle
{
	float fontHeight = 30f; // 字体高度
	int fontColor = Color.rgb(255, 0, 0); // 字体颜色
	String fontName = "Times New Roman"; // 字体名称
}

class JyDotStyle
{
	float dotDiameter = 15f; // 直径
	int dotColor = Color.rgb(1,255,5);// 颜色
	boolean isFilled = true; // 是否填充
}

class JyCurveFormat
{
	JyLineStyle coordinateStyle = new JyLineStyle(); // 坐标线
	JyLineStyle loadCurveStyle = new JyLineStyle(); // 加载曲线
	JyLineStyle unloadCurveStyle = new JyLineStyle(); // 卸载曲线
	JyLineStyle labelLineStyle = new JyLineStyle(); // 标注线

	JyFontStyle titleFontEn = new JyFontStyle(); // 标题字体(英文)
	JyFontStyle titleFontCn = new JyFontStyle(); // 标题字体(中文)
	JyFontStyle scaleFont = new JyFontStyle(); // 坐标刻度值字体
	JyFontStyle labelFont = new JyFontStyle(); // 标注字体

	JyDotStyle dotStyle = new JyDotStyle(); // 作图点

	int gridNum = 0; // 每个坐标刻度间的网格线数量，为 0 表示不画网格线
	float longScale = 14f; // 长刻度线高度
	float shortScale = 7f; // 短刻度线高度
	float arrowWidth = 45f; // 线箭头宽度
	float arrowHeight = 11f; // 线箭头高度
	int backColor = Color.rgb(0, 0, 0); // 背景颜色

	public JyCurveFormat()
	{
		// 线型
		coordinateStyle.lineColor = Color.rgb(255, 0, 0);

		loadCurveStyle.lineColor = Color.rgb(1,255,5);

		unloadCurveStyle.lineColor = Color.rgb(1,255,5);
		// unloadCurveStyle.dash = new float[]{ 6f, 4f };//卸载不用虚线

		labelLineStyle.lineColor = Color.rgb(255, 0, 0);
		labelLineStyle.dash = new float[]
				{ 8f, 2f, 2f, 2f };

		// 字体
		scaleFont.fontColor = Color.rgb(255,255, 255);

		labelFont.fontColor = Color.rgb(255, 255, 255);

		titleFontEn.fontHeight = 50f;
		titleFontEn.fontColor = Color.rgb(255, 255, 255);

		titleFontCn.fontHeight = 50f;
		titleFontCn.fontColor = Color.rgb(255, 255, 255);
		titleFontCn.fontName = "宋体";
	}
}

abstract class JyCurve
{
	protected JyDoc m_jyDoc;

	protected JyCurveFormat m_style;

	protected Paint m_penCoordinate;
	protected Paint m_penLoad;
	protected Paint m_penUnload;
	protected Paint m_penLabel;
	protected Paint m_penDot;

	protected Typeface m_fontTitleEn;
	protected Typeface m_fontTitleCn;
	protected Typeface m_fontScale;
	protected Typeface m_fontLable;

	protected RectF m_rcWindow; // 整个窗口
	protected RectF m_rcImage; // 整个图形区
	protected RectF m_rcCurve; // 曲线区域

	protected float m_fXMax; // 横坐标最大值
	protected float m_fXMin; // 横坐标最小值
	protected float m_fYMax; // 纵坐标最大值
	protected float m_fYMin; // 纵坐标最小值
	protected float m_fScale; // 内部缩放因子
	protected float m_fRatioXY; // 内部横纵比例

	protected String m_strScaleX; // 横坐标单位

	public String getScaleXString()
	{
		return m_strScaleX;
	}

	public void setScaleXString(String value)
	{
		m_strScaleX = value;
	}

	protected String m_strScaleY; // 纵坐标单位

	public String getScaleYString()
	{
		return m_strScaleY;
	}

	public void setScaleYString(String value)
	{
		m_strScaleY = value;
	}

	protected String m_strTitle; // 曲线名称

	public String getTitle()
	{
		return m_strTitle;
	}

	public void setTitle(String value)
	{
		m_strTitle = value;
	}

	protected int m_width; // 图像宽度

	public int getWidth()
	{
		return m_width;
	}

	public void setWidth(int value)
	{
		if (value > 15)
			m_width = value;
	}

	protected int m_height; // 图像高度

	public int getHeight()
	{
		return m_height;
	}

	public void setHeight(int value)
	{
		if (value > 15)
			m_height = value;
	}

	protected boolean m_isUp; // 纵坐标是否向上

	public boolean getIsUp()
	{
		return m_isUp;
	}

	public void setIsUp(boolean value)
	{
		m_isUp = value;
	}

	protected float m_ratio; // 横纵比例, X:Y，小于0表示自适应

	public float getRatio()
	{
		return m_ratio;
	}

	public void setRatio(float value)
	{
		if (Math.abs(value) > 0.1)
			m_ratio = value;
	}

	public JyCurve(JyDoc doc)
	{
		m_jyDoc = doc;
		m_style = new JyCurveFormat();

		m_width = m_jyDoc.getImageWidth();
		m_height = m_jyDoc.getImageHeight();
		m_isUp = false;
		m_ratio = -1.0f;

		m_fScale = 1.0f;
		m_fRatioXY = (float) m_width / (float) m_height;

		m_rcWindow = new RectF();
		// m_rcImage.set(m_rcWindow);
		// m_rcCurve.set(m_rcImage);
		m_rcImage = new RectF(m_rcWindow);
		m_rcCurve = new RectF(m_rcImage);

		m_fXMin = 0f;
		m_fYMin = 0f;
		m_fXMax = 10f;
		m_fYMax = 1f;
	}

	public void OnDraw(Canvas canvas)
	{
		calcMaxMinValue();
		onPrepareDC(canvas);
		createGdiObject();

		drawTitle(canvas);
		drawXCoordinate(canvas);
		drawYCoordinate(canvas);
		drawGrid(canvas);
		drawCurve(canvas);
		drawLabel(canvas);

		deleteGdiObject(canvas);
	}

	protected void calcMaxMinValue()
	{
		m_fXMin = m_fYMin = 0f;
		m_fXMax = 10f;
		m_fYMax = 1f;

		if (m_jyDoc.getJyDataInfo().nGradeCount <= 0)
			return;

		m_fXMax = Math.max(m_jyDoc.getJyDataInfo().fQMax, 10f);
		m_fYMin = Math.min(m_jyDoc.getJyDataInfo().fSMin, 0f);
		m_fYMax = Math.max(m_jyDoc.getJyDataInfo().fSMax, 0f);

		// 获得纵轴的最大、最小坐标值
		float fYDelta = m_fYMax - m_fYMin;
		if (fYDelta < 5.00001f)
			fYDelta = (int) (fYDelta - 0.00001f) + 1.0f;
		else if (fYDelta < 20.00001f)
			fYDelta = (int) (fYDelta * 1.2f);
		else
			fYDelta = (int) ((fYDelta - 0.00001) / 5.0f + 1.0f) * 5.0f;

		// 校正
		if (m_fYMin >= 0f)
			m_fYMax = m_fYMin + fYDelta;
		else if (m_fYMax <= 0f)
			m_fYMin = m_fYMax - fYDelta;
		else
		{
			m_fYMin = (float) Math.floor(m_jyDoc.getJyDataInfo().fSMin);
			m_fYMax = m_fYMin + fYDelta;

			if (m_fYMax <= m_jyDoc.getJyDataInfo().fSMax)
				m_fYMax += 1.0f;
		}
	}

	// 作图前重定位所有坐标
	protected void onPrepareDC(Canvas canvas)
	{
		Paint curPaint = new Paint();
		// 计算横纵坐标比例
		m_fRatioXY = (m_ratio > 0) ? m_ratio : (float) m_width
				/ (float) m_height;

		// 计算窗口大小
		m_rcWindow = new RectF(0f, 0f, m_width * m_fScale, m_height * m_fScale);
		if (m_rcWindow.width() < m_rcWindow.height() * m_fRatioXY)
			m_rcWindow.bottom = m_rcWindow.top + m_rcWindow.width()
					/ m_fRatioXY;
		else
			m_rcWindow.right = m_rcWindow.left + m_rcWindow.height()
					* m_fRatioXY;

		// 图像区缩小较短的边的 1% 以留出边界
		m_rcImage.set(m_rcWindow);

		float fMinSize = Math.min(m_rcImage.width(), m_rcImage.height());

		m_rcImage.left += (fMinSize * 0.01f);
		m_rcImage.top += (fMinSize * 0.01f);
		m_rcImage.right -= (fMinSize * 0.02f);
		m_rcImage.bottom -= (fMinSize * 0.02f);

		// 计算曲线区域, 为图像区的 85%
		m_rcCurve.set(m_rcImage);
		m_rcCurve.left += (m_rcImage.width() * 0.15f);
		// m_rcCurve.right -= (m_rcImage.width() * 0.15f);
		m_rcCurve.top += (m_isUp ? m_rcImage.height() * 0.1f : m_rcImage
				.height() * 0.15f);
		// m_rcCurve.bottom -= (m_rcImage.height() * 0.15f);

		// 计算各部分大小
		float fRatio = fMinSize / 1000f;

		m_style.coordinateStyle.lineWidth *= fRatio;
		m_style.loadCurveStyle.lineWidth *= fRatio;
		m_style.unloadCurveStyle.lineWidth *= fRatio;
		m_style.labelLineStyle.lineWidth *= fRatio;

		m_style.titleFontEn.fontHeight *= fRatio;
		m_style.titleFontCn.fontHeight *= fRatio;
		m_style.scaleFont.fontHeight *= fRatio;
		m_style.labelFont.fontHeight *= fRatio;

		m_style.dotStyle.dotDiameter *= fRatio;
		m_style.longScale *= fRatio;
		m_style.shortScale *= fRatio;

		m_style.arrowWidth *= fRatio;
		m_style.arrowHeight *= fRatio;

		canvas.translate((m_width - m_rcWindow.width()) / 2f,
				(m_height - m_rcWindow.height()) / 2f);
		canvas.drawColor(m_style.backColor);

		Rect curRect = new Rect(0, 0, m_width, m_height);

		curPaint.setStyle(Paint.Style.FILL);
		curPaint.setColor(m_style.backColor);
		// curPaint.setAntiAlias(true);// 设置抗锯齿
		canvas.drawRect(curRect, curPaint);

		// canvas.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		// canvas.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
		// canvas.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
		// RenderingHints.VALUE_FRACTIONALMETRICS_ON);
	}

	protected void createGdiObject()
	{
		if (m_style.coordinateStyle.dash.length == 0)
		{
			m_penCoordinate = new Paint();
			m_penCoordinate.setStrokeWidth(m_style.coordinateStyle.lineWidth);

		} else
		{
			m_penCoordinate = new Paint();
			m_penCoordinate.setStrokeWidth(m_style.coordinateStyle.lineWidth);
			m_penCoordinate.setStrokeCap(Paint.Cap.BUTT);
			m_penCoordinate.setStrokeJoin(Paint.Join.BEVEL);
			m_penCoordinate.setStrokeMiter(10f);
			m_penCoordinate.setPathEffect(new DashPathEffect(
					m_style.coordinateStyle.dash, 0f));
		}

		if (m_style.labelLineStyle.dash.length == 0)
		{
			m_penLabel = new Paint();
			m_penLabel.setStrokeWidth(m_style.labelLineStyle.lineWidth);
		} else
		{
			m_penLabel = new Paint();
			m_penLabel.setStrokeWidth(m_style.labelLineStyle.lineWidth);
			m_penLabel.setStrokeCap(Paint.Cap.BUTT);
			m_penLabel.setStrokeJoin(Paint.Join.BEVEL);
			m_penLabel.setStrokeMiter(10f);
			m_penLabel.setPathEffect(new DashPathEffect(
					m_style.labelLineStyle.dash, 0f));
		}

		if (m_style.loadCurveStyle.dash.length == 0)
		{
			m_penLoad = new Paint();
			m_penLoad.setStrokeWidth(m_style.loadCurveStyle.lineWidth);
		} else
		{
			m_penLoad = new Paint();
			m_penLoad.setStrokeWidth(m_style.loadCurveStyle.lineWidth);
			m_penLoad.setStrokeCap(Paint.Cap.BUTT);
			m_penLoad.setStrokeJoin(Paint.Join.BEVEL);
			m_penLoad.setStrokeMiter(10f);
			m_penLoad.setPathEffect(new DashPathEffect(
					m_style.loadCurveStyle.dash, 0f));
		}

		if (m_style.unloadCurveStyle.dash.length == 0)
		{
			m_penUnload = new Paint();
			m_penUnload.setStrokeWidth(m_style.unloadCurveStyle.lineWidth);
		} else
		{
			m_penUnload = new Paint();
			m_penUnload.setStrokeWidth(m_style.unloadCurveStyle.lineWidth);
			m_penUnload.setStrokeCap(Paint.Cap.BUTT);
			m_penUnload.setStrokeJoin(Paint.Join.BEVEL);
			m_penUnload.setStrokeMiter(10f);
			m_penUnload.setPathEffect(new DashPathEffect(
					m_style.unloadCurveStyle.dash, 0f));
		}

		m_penDot = new Paint();
		m_penDot.setStrokeWidth(1f);

		m_fontTitleEn = Typeface.DEFAULT;
		m_fontTitleCn = Typeface.DEFAULT;
		m_fontScale = Typeface.DEFAULT;
		m_fontLable = Typeface.DEFAULT;
		/*
		 * m_fontTitleEn = new Font(m_style.titleFontEn.fontName,
		 * Font.PLAIN,(int) m_style.titleFontEn.fontHeight); m_fontTitleCn = new
		 * Font(m_style.titleFontCn.fontName, Font.PLAIN, (int)
		 * m_style.titleFontCn.fontHeight); m_fontScale = new
		 * Font(m_style.scaleFont.fontName, Font.PLAIN, (int)
		 * m_style.scaleFont.fontHeight); m_fontLable = new
		 * Font(m_style.labelFont.fontName, Font.PLAIN, (int)
		 * m_style.labelFont.fontHeight);
		 */
	}

	protected void deleteGdiObject(Canvas canvas)
	{
		// canvas.dispose();
	}

	// 画箭头
	protected void drawArrow(Canvas canvas, PointF TopPoint, boolean bVert)
	{
		Paint curPaint = new Paint();
		PointF[] ptArrow = new PointF[3];
		ptArrow[0] = new PointF(TopPoint.x, TopPoint.y);
		ptArrow[1] = new PointF(TopPoint.x, TopPoint.y);
		ptArrow[2] = new PointF(TopPoint.x, TopPoint.y);

		if (bVert)
		{
			if (m_isUp)
				ptArrow[1].y = ptArrow[2].y = TopPoint.y + m_style.arrowWidth;
			else
				ptArrow[1].y = ptArrow[2].y = TopPoint.y - m_style.arrowWidth;

			ptArrow[1].x = TopPoint.x - m_style.arrowHeight / 2f;
			ptArrow[2].x = TopPoint.x + m_style.arrowHeight / 2f;
		} else
		{
			ptArrow[1].x = ptArrow[2].x = TopPoint.x - m_style.arrowWidth;
			ptArrow[1].y = TopPoint.y - m_style.arrowHeight / 2f;
			ptArrow[2].y = TopPoint.y + m_style.arrowHeight / 2f;
		}

		Path path = new Path();
		path.moveTo(ptArrow[0].x, ptArrow[0].y);
		path.lineTo(ptArrow[1].x, ptArrow[1].y);
		path.lineTo(ptArrow[2].x, ptArrow[2].y);
		path.lineTo(ptArrow[0].x, ptArrow[0].y);

		curPaint.setColor(m_style.coordinateStyle.lineColor);
		curPaint.setStyle(Paint.Style.FILL);
		canvas.drawPath(path, curPaint);
	}

	// 画标题
	protected void drawTitle(Canvas canvas)
	{
		drawTitle(canvas, m_strTitle);
	}

	protected void drawTitle(Canvas canvas, String strTitle)
	{
		Paint curPaint = new Paint();
		if (strTitle == null)
			return;

		if (strTitle.length() <= 0)
			return;

		// 计算标题位置

		curPaint.setTypeface(m_fontTitleEn);// 这里使用安卓默认字体
		// curPaint.setStrokeWidth(m_style.titleFontEn.fontHeight);
		curPaint.setTextSize(m_style.titleFontEn.fontHeight);

		curPaint.setColor(m_style.titleFontEn.fontColor);
		Rect rectText = new Rect();
		curPaint.getTextBounds(strTitle, 0, strTitle.length(), rectText);

		PointF pointText = new PointF(
				(float) (m_rcImage.centerX() - rectText.width() / 2.0),
				(m_rcCurve.top - m_rcImage.top) / 4f + rectText.height());
		/*
		 * for (int i = 0; i < strTitle.length(); i++) { char c =
		 * strTitle.charAt(i); Font f = m_fontTitleEn.canDisplay(c) ?
		 * m_fontTitleEn : m_fontTitleCn;
		 *
		 * canvas.setFont(f);
		 *
		 * canvas.drawString(strTitle.substring(i, i + 1), pointText.x,
		 * pointText.y);
		 *
		 * rectText = f.getStringBounds(new char[] { c }, 0, 1,
		 * canvas.getFontRenderContext()); pointText.x += (float)
		 * rectText.getWidth(); }
		 */
		canvas.drawText(strTitle, pointText.x, pointText.y, curPaint);
		/*
		 * for (int i = 0; i < strTitle.length(); i++) { char c =
		 * strTitle.charAt(i); canvas.drawText(strTitle, i, i + 1, pointText.x,
		 * pointText.y, curPaint); curPaint.getTextBounds(new char[] { c }, 0,
		 * 1, rectText); pointText.x += (float) rectText.width(); }
		 */
	}

	protected void drawXCoordinate(Canvas canvas)
	{
		// 画坐标轴
		Paint curPaint = new Paint();
		curPaint.set(m_penCoordinate);
		curPaint.setColor(m_style.coordinateStyle.lineColor);
		curPaint.setStrokeWidth(0f);// 坐标轴线条宽度

		if (m_isUp)
		{
			canvas.drawLine(m_rcCurve.left, m_rcCurve.bottom, m_rcCurve.right,
					m_rcCurve.bottom, curPaint);
			drawArrow(canvas, new PointF(m_rcCurve.right, m_rcCurve.bottom),
					false);
		} else
		{
			canvas.drawLine(m_rcCurve.left, m_rcCurve.top, m_rcCurve.right,
					m_rcCurve.top, curPaint);
			drawArrow(canvas, new PointF(m_rcCurve.right, m_rcCurve.top), false);
		}

		// 写坐标单位
		if ((m_strScaleX != null) && m_strScaleX.length() != 0)
		{
			curPaint.setColor(m_style.scaleFont.fontColor);
			curPaint.setTypeface(m_fontScale);
			// curPaint.setStrokeWidth(m_style.scaleFont.fontHeight);
			curPaint.setTextSize(m_style.scaleFont.fontHeight);
			Rect rectText = new Rect();

			curPaint.getTextBounds(m_strScaleX, 0, m_strScaleX.length(),
					rectText);

			PointF pointText = new PointF();
			pointText.x = m_rcCurve.right - rectText.width();
			pointText.y = m_isUp ? (m_rcCurve.bottom) - m_style.longScale
					* 1.5f : m_rcCurve.top + rectText.height()
					+ m_style.longScale / 2f;

			canvas.drawText(m_strScaleX, pointText.x, pointText.y, curPaint);
		}
	}

	protected void drawYCoordinate(Canvas canvas)
	{
		// 画坐标轴

		Paint curPaint = new Paint();
		curPaint.set(m_penCoordinate);
		curPaint.setColor(m_style.coordinateStyle.lineColor);
		curPaint.setStrokeWidth(0f);// 坐标轴线条宽度

		canvas.drawLine(m_rcCurve.left, m_rcCurve.top, m_rcCurve.left,
				m_rcCurve.bottom, curPaint);
		if (m_isUp)
			drawArrow(canvas, new PointF(m_rcCurve.left, m_rcCurve.top), true);
		else
			drawArrow(canvas, new PointF(m_rcCurve.left, m_rcCurve.bottom),
					true);

		curPaint.setColor(m_style.scaleFont.fontColor);
		curPaint.setTypeface(m_fontScale);
		// curPaint.setStrokeWidth(m_style.scaleFont.fontHeight);
		curPaint.setTextSize(m_style.scaleFont.fontHeight);

		PointF pointText = new PointF();

		// 写坐标单位
		if (((m_strScaleY != null)) && m_strScaleY.length() != 0)
		{
			pointText.x = m_rcCurve.left + m_style.longScale * 1.5f;
			Rect rectText = new Rect();
			curPaint.getTextBounds(m_strScaleY, 0, m_strScaleY.length(),
					rectText);
			pointText.y = m_isUp ? m_rcCurve.top + rectText.height()
					: (float) (m_rcCurve.bottom - rectText.height() / 2);

			canvas.drawText(m_strScaleY, pointText.x, pointText.y, curPaint);
		}

		// 写坐标值
		pointText.x = m_rcCurve.left - m_style.longScale * 8f / 5f;
		float fHeight = m_rcCurve.height() * 9f / 10f;
		String strText;

		for (int i = 0; i < 11; i++)
		{
			pointText.y = m_isUp ? m_rcCurve.bottom - fHeight * i / 10f
					: m_rcCurve.top + fHeight * i / 10f;

			float fValue = m_fYMin + (m_fYMax - m_fYMin) * i / 10f;
			strText = String.format("%.2f", fValue);

			Rect rectText = new Rect();
			curPaint.getTextBounds(strText, 0, strText.length(), rectText);

			canvas.drawText(strText, pointText.x - rectText.width(),
					pointText.y + (float) rectText.height() / 3, curPaint);
		}

		// 如果有网格线，就不用画坐标刻度了
		if (m_style.gridNum > 0)
			return;

		// 画坐标刻度
		curPaint.setStrokeWidth(m_style.coordinateStyle.lineWidth);
		curPaint.setColor(m_style.coordinateStyle.lineColor);
		curPaint.setStrokeWidth(0f);// 坐标刻度线条宽度

		float x1 = m_rcCurve.left;
		float x2 = m_rcCurve.left - m_style.longScale;
		float x3 = m_rcCurve.left - m_style.shortScale;
		for (int i = 0; i < 11; i++)
		{
			float y = m_isUp ? (m_rcCurve.bottom - fHeight * i / 10f)
					: (m_rcCurve.top + fHeight * i / 10f);

			if (i > 0)
			{
				canvas.drawLine(x1, y, x2, y, curPaint);
			}

			if (i < 10)
			{
				for (int j = 1; j < 5; j++)
				{
					y = m_isUp ? (m_rcCurve.bottom - fHeight * (i * 5 + j)
							/ 50f) : (m_rcCurve.top + fHeight * (i * 5 + j)
							/ 50f);
					canvas.drawLine(x1, y, x3, y, curPaint);
				}
			}
		}
	}

	protected void drawGrid(Canvas canvas)
	{
	}

	protected PointF getZeroPoint()
	{
		float fHeight = m_rcCurve.height() * 0.9f;
		float fYFullScale = m_fYMax - m_fYMin;
		float fYDelta = -m_fYMin / fYFullScale;

		PointF pt = new PointF();
		pt.x = m_rcCurve.left;
		pt.y = m_isUp ? m_rcCurve.top + m_rcCurve.height() - fHeight * fYDelta
				: m_rcCurve.top + fHeight * fYDelta;

		return pt;
	}

	protected void drawCurve(Canvas canvas)
	{
	}

	protected void drawLabel(Canvas canvas)
	{
	}
}
